package com.xx.sg.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xx.sg.dbw.entity.*;
import com.xx.sg.dbw.service.*;
import com.xx.sg.own.entity.Camera;
import com.xx.sg.own.entity.CommunicationTerminal;
import com.xx.sg.own.entity.WatchTower;
import com.xx.sg.own.service.CameraService;
import com.xx.sg.own.service.CommunicationTerminalService;
import com.xx.sg.own.service.FacilityService;
import com.xx.sg.own.service.WatchTowerService;
import com.xx.sg.util.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@RestController
@RequestMapping("/facility")
@Tag(name = "设施管理Api", description = "设施管理Api")
public class FacilityController {

    @Autowired
    private FacilityService facilityService;
    @Autowired
    private TarmacService tarmacService;
    @Autowired
    private ReserveService reserveService;
    @Autowired
    private FireTeamService fireTeamService;
    @Autowired
    private ProtectUnitService protectUnitService;
    @Autowired
    private WatchTowerService watchTowerService;
    @Autowired
    private WaterPointService waterPointService;
    @Autowired
    private ResidentAreaService residentAreaService;
    @Autowired
    private PublicityTabletService publicityTabletService;
    @Autowired
    private IsolationZoneService isolationZoneService;
    @Autowired
    private FirePoleService firePoleService;
    @Autowired
    private CommunicationService communicationService;
    @Autowired
    private ChecksiteService checksiteService;
    @Autowired
    private AirStationService airStationService;
    @Autowired
    private GasService gasService;
    @Autowired
    private LargeFireDevService largeFireDevService;
    @Autowired
    private SummerGarrisonService summerGarrisonService;
    @Autowired
    private SpringGarrisonService springGarrisonService;
    @Autowired
    private CameraService cameraService;
    @Autowired
    private CommunicationTerminalService communicationTerminalService;

    @GetMapping("/rangeFacility")
    @Operation(summary = "查询数据", description = "查询数据")
    @ApiResponse(
            responseCode = "200",
            description = "watchTower 瞭望塔, waterPoint 取水点,tarmac 停机坪,residentArea 居民点,reserve 防火物资,publicityTablet 防火宣传碑,protectUnit 重点保护单位," +
                    "isolationZone 隔离带,fireTeam 防火队,firePole 防火宣传牌,communication 通讯设备,checksite 防火检查点,airStation 航空护林站,largeFireDev 大型扑救设备，" +
                    "gas 加油站,springGarrison 春季靠前驻防点,summerGarrison 夏季靠前驻防点,camera 监控点位,communicationTerminal 对讲机"
    )
    public Map rangeFacility(@RequestParam String longitude,
                             @RequestParam String latitude,
                             @RequestParam String radius) throws ExecutionException, InterruptedException {

        Executor executor = Executors.newFixedThreadPool(10);

        //瞭望塔
        CompletableFuture<List<WatchTower>> watchTowerTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<WatchTower> wrapper = new LambdaQueryWrapper<>();
            wrapper.apply(
                    "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                            "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                    longitude, latitude, radius
            );
            return watchTowerService.list(wrapper);
        }, executor);

        //取水点
        CompletableFuture<List<WaterPoint>> waterPointTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<WaterPoint> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(WaterPoint::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return waterPointService.list(wrapper);
        }, executor);

        //停机坪
        CompletableFuture<List<Tarmac>> tarmacTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Tarmac> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Tarmac::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return tarmacService.list(wrapper);
        }, executor);

        //居民点
        CompletableFuture<List<ResidentArea>> residentAreaTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<ResidentArea> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ResidentArea::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return residentAreaService.list(wrapper);
        }, executor);

        //防火物资
        CompletableFuture<List<Reserve>> reserveTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Reserve> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Reserve::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return reserveService.list(wrapper);
        }, executor);

        //防火宣传碑
        CompletableFuture<List<PublicityTablet>> publicityTabletTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<PublicityTablet> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PublicityTablet::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return publicityTabletService.list(wrapper);
        }, executor);

        //重点保护单位
        CompletableFuture<List<ProtectUnit>> protectUnitTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<ProtectUnit> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ProtectUnit::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return protectUnitService.list(wrapper);
        }, executor);

        //隔离带
//        CompletableFuture<List<IsolationZone>> isolationZoneTask = CompletableFuture.supplyAsync(() -> {
//            LambdaQueryWrapper<IsolationZone> wrapper = new LambdaQueryWrapper<>();
//            wrapper.eq(IsolationZone::getDeleteFlag, 0)
//                    .apply(
//                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
//                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
//                            longitude, latitude, radius
//                    );
//            return isolationZoneService.list(wrapper);
//        }, executor);

        //防火队
        CompletableFuture<List<FireTeam>> fireTeamTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<FireTeam> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FireTeam::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return fireTeamService.list(wrapper);
        }, executor);

        //防火宣传牌
        CompletableFuture<List<FirePole>> firePoleTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<FirePole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FirePole::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return firePoleService.list(wrapper);
        }, executor);

        //通讯设备
        CompletableFuture<List<Communication>> communicationTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Communication> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Communication::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return communicationService.list(wrapper);
        }, executor);

        //防火检查点
        CompletableFuture<List<Checksite>> checksiteTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Checksite> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Checksite::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return checksiteService.list(wrapper);
        }, executor);

        //航空护林站
        CompletableFuture<List<AirStation>> airStationTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<AirStation> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(AirStation::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return airStationService.list(wrapper);
        }, executor);

        //大型扑救设备
        CompletableFuture<List<LargeFireDev>> largeFireDevTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<LargeFireDev> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(LargeFireDev::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude_::double precision, latitude_::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return largeFireDevService.list(wrapper);
        }, executor);

        //加油站
        CompletableFuture<List<Gas>> gasTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Gas> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Gas::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude_::double precision, latitude_::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return gasService.list(wrapper);
        }, executor);

        //春季靠前驻防点
        CompletableFuture<List<SpringGarrison>> springGarrisonTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<SpringGarrison> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SpringGarrison::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude_::double precision, latitude_::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return springGarrisonService.list(wrapper);
        }, executor);

        //夏季靠前驻防点
        CompletableFuture<List<SummerGarrison>> summerGarrisonTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<SummerGarrison> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SummerGarrison::getDeleteFlag, 0)
                    .apply(
                            "ST_DWithin(ST_MakePoint(longitude_::double precision, latitude_::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return summerGarrisonService.list(wrapper);
        }, executor);

        //监控点位
        CompletableFuture<List<Camera>> cameraTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Camera> wrapper = new LambdaQueryWrapper<>();
            wrapper.apply(
                            "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                                    "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                            longitude, latitude, radius
                    );
            return cameraService.list(wrapper);
        }, executor);

        //监控点位
        CompletableFuture<List<CommunicationTerminal>> communicationTerminalTask = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<CommunicationTerminal> wrapper = new LambdaQueryWrapper<>();

            wrapper.apply(
                    "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                            "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                    longitude, latitude, radius
            );
            return communicationTerminalService.list(wrapper);
        }, executor);



        CompletableFuture<Map<String, Object>> allTasks = CompletableFuture.allOf(
//                isolationZoneTask,cameraTask
                watchTowerTask, waterPointTask, tarmacTask, residentAreaTask, reserveTask, publicityTabletTask,
                protectUnitTask, fireTeamTask, firePoleTask, communicationTask, checksiteTask,
                airStationTask, largeFireDevTask, gasTask, springGarrisonTask, summerGarrisonTask,communicationTerminalTask
        ).thenApply(v -> {
            Map<String, Object> result = new HashMap<>();
            try {
                result.put("watchTower", watchTowerTask.get());
                result.put("waterPoint", waterPointTask.get());
                result.put("tarmac", tarmacTask.get());
                result.put("residentArea", residentAreaTask.get());
                result.put("reserve", reserveTask.get());
                result.put("publicityTablet", publicityTabletTask.get());
                result.put("protectUnit", protectUnitTask.get());
//                result.put("isolationZone", isolationZoneTask.get());
                result.put("fireTeam", fireTeamTask.get());
                result.put("firePole", firePoleTask.get());
                result.put("communication", communicationTask.get());
                result.put("checksite", checksiteTask.get());
                result.put("airStation", airStationTask.get());
                result.put("largeFireDev", largeFireDevTask.get());
                result.put("gas", gasTask.get());
                result.put("springGarrison", springGarrisonTask.get());
                result.put("summerGarrison", summerGarrisonTask.get());
                result.put("communicationTerminal", communicationTerminalTask.get());
//                result.put("camera", cameraTask.get());
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException("异步任务执行失败", e);
            }
            return result;
        });

        Map<String, Object> res = new HashMap<>();
        res.put("success", true);
        res.put("code", 200);
        res.put("data", allTasks.get());
        res.put("message", "成功");
        return res;
    }

    @GetMapping("/rangeFacilityCamera")
    @Operation(summary = "查询监控数据", description = "查询监控数据")
    public Map rangeFacilityCamera(@RequestParam String longitude,
                             @RequestParam String latitude,
                             @RequestParam String radius)  {

        LambdaQueryWrapper<Camera> wrapper = new LambdaQueryWrapper<>();
        wrapper.apply(
                "ST_DWithin(ST_MakePoint(longitude::double precision, latitude::double precision)::geography, " +
                        "ST_MakePoint({0}::double precision, {1}::double precision)::geography, {2}::double precision)",
                longitude, latitude, radius
        );
        List<Camera> list = cameraService.list(wrapper);
        Map<String, Object> res = new HashMap<>();
        res.put("success", true);
        res.put("code", 200);
        res.put("data",list);
        res.put("message", "成功");
        return res;
    }

    @GetMapping("/getSearchKeyWord")
    @Operation(summary = "获取搜素关键字", description = "获取搜素关键字")
    public R getSearchKeyWord(@RequestParam String keyword) {
        return R.success(facilityService.getKeyWords(keyword));
    }

    @GetMapping("/search")
    @Operation(summary = "数据搜索", description = "数据搜索")
    public R search(@RequestParam String keyword) {
        return R.success(facilityService.getDtaList(keyword));
    }


}
